#pragma once
#include <iostream>
#include <pthread.h>
#include <string>
#include <functional>
#include <cstring>
#include <unistd.h>
#include <vector>
#include "Mutex.hpp"

#include <iostream>
#include <string>
#include <pthread.h>
#include <cstdio>
#include <cstring>
#include <functional>

// namespace MypthreadModule
// {
//     static uint32_t number = 1; // bug

//     class Thread
//     {
//         using func_t = std::function<void()>; // 暂时这样写，完全够了
//     private:
//         void EnableDetach()
//         {
//             _isdetach = true;
//         }
//         void EnableRunning()
//         {
//             _isrunning = true;
//         }
//         static void *Routine(void *args) // 属于类内的成员函数，默认包含this指针！
//         {
//             Thread *self = static_cast<Thread *>(args);
//             self->EnableRunning();
//             if (self->_isdetach)
//                 self->Detach();
//             pthread_setname_np(self->_tid, self->_name.c_str());
//             self->_func(); // 回调处理

//             return nullptr;
//         }
//         // bug
//     public:
//         Thread(func_t func)
//             : _tid(0),
//               _isdetach(false),
//               _isrunning(false),
//               res(nullptr),
//               _func(func)
//         {
//             _name = "thread-" + std::to_string(number++);
//         }
//         void Detach()
//         {
//             if (_isdetach)
//                 return;
//             if (_isrunning)
//                 pthread_detach(_tid);
//             EnableDetach();
//         }

//         bool Start()
//         {
//             if (_isrunning)
//                 return false;
//             int n = pthread_create(&_tid, nullptr, Routine, this);
//             if (n != 0)
//             {
//                 return false;
//             }
//             else
//             {
//                 return true;
//             }
//         }
//         bool Stop()
//         {
//             if (_isrunning)
//             {
//                 int n = pthread_cancel(_tid);
//                 if (n != 0)
//                 {
//                     return false;
//                 }
//                 else
//                 {
//                     _isrunning = false;
//                     return true;
//                 }
//             }
//             return false;
//         }
//         void Join()
//         {
//             if (_isdetach)
//             {
//                 return;
//             }
//             int n = pthread_join(_tid, &res);
//             if (n != 0)
//             {
//             }
//             else
//             {
//             }
//         }
//         pthread_t Id()
//         {
//             return _tid;
//         }
//         ~Thread()
//         {
//         }

//     private:
//         pthread_t _tid;
//         std::string _name;
//         bool _isdetach;
//         bool _isrunning;
//         void *res;
//         func_t _func;
//     };
// }

namespace MypthreadModule
{
    using namespace MutexModule;

    /* 用于标识线程的name */
    static unsigned int number = 1;
    Mutex _mutex; /* 互斥锁 */

    /* 用于标识当前线程的状态 */
    enum class STATUS
    {
        NEW,     /* 新创建 */
        RUNNING, /* 运行中 */
        STOP     /* 暂停中 */
    };
    /* 包装器：包装回调函数 */
    using func_t = std::function<void()>;

    /* Thread类 */
    class Thread
    {
    public:
        explicit Thread(func_t routine)
            : _tid(0), _pid(getpid()), _is_detachable(false),
              _routine(routine), _ret(nullptr), _status(STATUS::NEW)
        {
            _name = "thread-" + std::to_string(number++);
            Start();
        }

        /* 函数回调接口 */
        static void *Routine(void *args)
        {
            int n = pthread_detach(pthread_self());
            Thread *t = static_cast<Thread *>(args);
            char name[16];
            strncpy(name, t->_name.c_str(), sizeof(name) - 1);
            name[15] = '\0';
            pthread_setname_np(t->_tid, name);
            t->_routine();
            t->_status = STATUS::STOP;
            return nullptr;
        }

        /* 创建线程 */
        bool Start()
        {
            if (_status == STATUS::RUNNING)
                return false;
            int n = pthread_create(&_tid, nullptr, Routine, this);
            if (n != 0)
                return false;
            _status = STATUS::RUNNING;
            return true;
        }

        bool Detach()
        {
            // if (_is_detachable || _status != STATUS::RUNNING)
            // {
            //     return false;
            // }
            // int n = pthread_detach(_tid);
            // if (n == 0)
            // {
            //     std::cout << "线程分离成功" << std::endl;
            //     _is_detachable = true;
            //     return true;
            // }
            // return false;
        }

        bool Join()
        {
            if (_is_detachable || _status != STATUS::RUNNING)
                return false;
            int n = pthread_join(_tid, &_ret);
            if (n != 0)
                return false;
            _status = STATUS::STOP;
            return true;
        }

        bool Cancel()
        {
            /* 取消的进程状态必须属于执行中的进程 */
            if (_status != STATUS::RUNNING)
            {
                return false;
            }

            int n = pthread_cancel(_tid);
            if (n != 0)
            {
                return false;
            }
            /* 调整进程状态 */
            _status = STATUS::STOP;
            return true;
        }

        void *GetRet()
        {
            return _ret;
        }

        std::string Name()
        {
            return _name;
        }

        pthread_t GetTid()
        {
            return _tid;
        }

        ~Thread()
        {
            if (_status == STATUS::RUNNING)
            {
                if (!_is_detachable)
                {
                    pthread_join(_tid, nullptr);
                }
                else
                {
                    pthread_detach(_tid);
                }
            }
        }

    private:
        pthread_t _tid;      /* 线程tid */
        pid_t _pid;          /* 进程pid */
        std::string _name;   /* 线程name */
        bool _is_detachable; /* 线程是否分离 */
        func_t _routine;     /* 线程执行的函数 */
        void *_ret;          /* 用于获取返回值 */
        STATUS _status;      /* 线程状态 */
    };

}
